package com.odontosis.relatorio.reciboperiodo;

import java.awt.Color;
import java.io.ByteArrayOutputStream;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;

import com.lowagie.text.BadElementException;
import com.lowagie.text.Cell;
import com.lowagie.text.Document;
import com.lowagie.text.Font;
import com.lowagie.text.PageSize;
import com.lowagie.text.Paragraph;
import com.lowagie.text.Phrase;
import com.lowagie.text.Table;
import com.lowagie.text.pdf.PdfPageEvent;
import com.lowagie.text.pdf.PdfWriter;
import com.odontosis.entidade.Paciente;
import com.odontosis.entidade.Recibo;
import com.odontosis.entidade.TipoRecibo;
import com.odontosis.service.ReciboService;
import com.odontosis.util.StringUtilsOdontosis;
import com.odontosis.view.OdontosisAction;

public class AcaoRelatorioRecibo extends OdontosisAction<ReciboService> {
	
	/**
	 * Mtodo principal da ao. 
	 */
	@Override
	public ActionForward execute(ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response) throws Exception {
		FormRelatorioRecibo formRelatorio = (FormRelatorioRecibo) actionForm;

		return super.execute(mapping, actionForm, request, response);
	}
	
	public ActionForward vizualizar(ActionMapping mapping, ActionForm actionForm,
			HttpServletRequest request, HttpServletResponse response) throws Exception {
		FormRelatorioRecibo formRelatorio = (FormRelatorioRecibo) actionForm;
		
		
		SimpleDateFormat formato = new SimpleDateFormat("dd/MM/yyyy");
		Calendar inicio = Calendar.getInstance();
		inicio.setTime(formato.parse(formRelatorio.getDataInicial()));
		inicio.set(Calendar.HOUR, 0);
		inicio.set(Calendar.MINUTE, 0);
		inicio.set(Calendar.SECOND, 0);
		
		Calendar fim = Calendar.getInstance();
		fim.setTime(formato.parse(formRelatorio.getDataFinal()));
		fim.set(Calendar.HOUR, 23);
		fim.set(Calendar.MINUTE, 59);
		fim.set(Calendar.SECOND, 59);
		
		TipoRecibo tipoRecibo = null;
		if(!StringUtilsOdontosis.isVazia(formRelatorio.getTipo())){
			tipoRecibo = TipoRecibo.recuperarPorCodigo(Integer.parseInt(formRelatorio.getTipo())); 
		}
		
		gerarRelatorio(inicio.getTime(), fim.getTime() , formRelatorio.getPaciente(),tipoRecibo, response);
		
		return null;
	}
	
	
	public void gerarRelatorio(Date inicio, Date fim, String paciente,TipoRecibo tipo, HttpServletResponse response){
		try{
			//fontes
			Font fontItem = new Font(Font.HELVETICA, 9, Font.NORMAL);
	        Font fontTotal = new Font(Font.HELVETICA, 9, Font.BOLD);
	        Font fonteTitulo = new Font(Font.HELVETICA, 10, Font.BOLD);
	        Font fonteCabecalho = new Font(Font.HELVETICA, 12, Font.BOLD);
	        
			//inicializa documento
			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			Document document = new Document(PageSize.A4.rotate());
			PdfWriter writer = PdfWriter.getInstance(document, baos);
			document.open();
			
			Collection<Recibo> resultado = service.relatorioPorPacientePeridoTipo(paciente, inicio, fim,tipo);
			
			//define o titulo
			SimpleDateFormat formata = new SimpleDateFormat("dd/MM/yyyy");
			String dataInicio = formata.format(inicio.getTime());
			String dataFim = formata.format(fim.getTime());
			
			
			
			String periodo =  dataInicio + " até "+ dataFim;
			Paragraph paragrafoTitulo = new Paragraph(new Phrase("Relatório dos Recibos Emitidos \n  de "+periodo , fonteCabecalho));
            paragrafoTitulo.setAlignment(1);
            document.add(paragrafoTitulo);
			
			//cria a tabela
			float [] tamanhos = {0.75f,2.3f,1.3f,0.8f,1f,1.3f,0.9f,0.8f};
			Table table = criarObjetoTabela(8, tamanhos);
			
			criarCabecalho(fonteCabecalho, table);
			
			
			double total = 0.0;
			//totalizadores
			double pfcomcpf = 0;
			double pfsemcpf = 0;
			double pj = 0;
			double cancelados = 0;
			for (Recibo recibo : resultado) {
				
				Cell cell = new Cell(new Phrase("Remover", fonteTitulo));
				cell.setColspan(8);
				table.addCell(cell);
				table.addCell(cell);
				table.addCell(cell);
				if(!writer.fitsPage(table)) {
					table.deleteLastRow();
					table.deleteLastRow();
					table.deleteLastRow();
					document.add(table);
					document.newPage();
					table = criarObjetoTabela(8, tamanhos);
					//criarCabecalho(fonteCabecalho, table);
				}else {
					table.deleteLastRow();
					table.deleteLastRow();
					table.deleteLastRow();
				}
				
				
					if(recibo.isAtivo()) {
						switch (recibo.getTipoRecibo()) {
						case PFCOMCPF:
							pfcomcpf += recibo.getValor().doubleValue();
							break;
						case PFSEMCPF:
							pfsemcpf += recibo.getValor().doubleValue();
							break;
						case PJ:
							pj += recibo.getValor().doubleValue();
							break;
						default:
							break;
						}
					} else {
						cancelados += recibo.getValor().doubleValue();
					}
					
					Color color = new Color(255,255,255);
					if(!recibo.isAtivo()) {
						color = new Color(255,0,0);
					}
				
					Cell ipsm = new Cell(new Phrase(StringUtilsOdontosis.colocaZeros(recibo.getId().toString(),10), fontItem));
					ipsm.setBackgroundColor(color);
					table.addCell(ipsm);
					
					Paciente pacienteServico = recibo.getPagamento().getServico().getPacienteServico();
					Cell paciente1 = new Cell(new Phrase(StringUtilsOdontosis.colocaZeros(pacienteServico.getNumeroPasta(), 10) + " - " +pacienteServico.getNome(), fontItem));
					paciente1.setBackgroundColor(color);
					table.addCell(paciente1);
					
					Cell tipoRec = new Cell(new Phrase( recibo.getTipoRecibo().getDescricao(), fontItem));
					tipoRec.setBackgroundColor(color);
					table.addCell(tipoRec);
					
					Cell data = new Cell(new Phrase(formata.format(recibo.getData()), fontItem));
					data.setBackgroundColor(color);
					table.addCell(data);
					
					String usuarioNome = recibo.getUsuario() != null ? recibo.getUsuario().getNome() : "-";
					Cell usuario = new Cell(new Phrase(usuarioNome, fontItem));
					usuario.setBackgroundColor(color);
					table.addCell(usuario);
					
					String formatDataCancelamento = recibo.getDataCancelamento() != null ? formata.format(recibo.getDataCancelamento()) : "";
					String usuarioCancelamento = " - " + (recibo.getUsuarioCancelamento() != null ? recibo.getUsuarioCancelamento().getNome(): "");
					String justificativaCancelamento = (recibo.getJustificativaCancelamento() != null ? "\n" + recibo.getJustificativaCancelamento() : "");
					Cell cancelamento = new Cell(new Phrase(formatDataCancelamento + usuarioCancelamento + justificativaCancelamento, fontItem));
					cancelamento.setBackgroundColor(color);
					table.addCell(cancelamento);
					
					Cell vencimento = new Cell(new Phrase(recibo.getNumeroParcela() + " - " + recibo.getPagamento().getMesVencimento() +"/"+ recibo.getPagamento().getAnoVencimento(), fontItem));
					vencimento.setBackgroundColor(color);
					vencimento.setHorizontalAlignment(Cell.ALIGN_CENTER);
					table.addCell(vencimento);
					
					Cell valor = new Cell(new Phrase(StringUtilsOdontosis.formatarDouble(recibo.getValor().doubleValue()), fontItem));
					valor.setBackgroundColor(color);
					table.addCell(valor);	
					
					total += recibo.getValor().doubleValue();
				
				
			}
			
			
			 
			
			Cell rodape = new Cell(new Phrase("(Valor Total - Cancelados)\nRecibos Pessoa Física sem CPF\nRecibos Pessoa Física com CPF\nRecibos Pessoa Jurídica\nCancelados",fontTotal));
			rodape.setColspan(7);
			rodape.setBackgroundColor(new Color(236, 235, 234));    
			table.addCell(rodape);
			
			Cell totaliza = new Cell(new Phrase(StringUtilsOdontosis.formatarDouble(total - cancelados) +"\n"+StringUtilsOdontosis.formatarDouble(pfsemcpf) +"\n" + StringUtilsOdontosis.formatarDouble(pfcomcpf) +"\n" + StringUtilsOdontosis.formatarDouble(pj) + "\n" + StringUtilsOdontosis.formatarDouble(cancelados),fontTotal));
			totaliza.setBackgroundColor(new Color(236, 235, 234));    
			table.addCell(totaliza);
			
			
			document.add(table);
			document.close();
			response.setContentType("application/pdf");
			response.setContentLength(baos.size());
			ServletOutputStream out = response.getOutputStream();
			baos.writeTo(out);
			out.flush();
			
		
		}catch (Exception e) {
			e.printStackTrace();
		}
		
	}

	private void criarCabecalho(Font fonteCabecalho, Table table)
			throws BadElementException {
		Cell t1 = new Cell(new Phrase("Nº Recibo", fonteCabecalho));
		t1.setBackgroundColor(new Color(236, 235, 234));    
		table.addCell(t1);
		
		Cell t2 = new Cell(new Phrase("Paciente", fonteCabecalho));
		t2.setBackgroundColor(new Color(236, 235, 234));
		table.addCell(t2);
		
		Cell t6 = new Cell(new Phrase("Tipo", fonteCabecalho));
		t6.setBackgroundColor(new Color(236, 235, 234));
		table.addCell(t6);
		
		Cell t3 = new Cell(new Phrase("Data", fonteCabecalho));
		t3.setBackgroundColor(new Color(236, 235, 234));
		table.addCell(t3);
		
		Cell t4 = new Cell(new Phrase("Responsável", fonteCabecalho));
		t4.setBackgroundColor(new Color(236, 235, 234));
		table.addCell(t4);
		
		Cell t7 = new Cell(new Phrase("Cancelamento", fonteCabecalho));
		t7.setBackgroundColor(new Color(236, 235, 234));
		table.addCell(t7);
		
		Cell t8 = new Cell(new Phrase("Parcela - Vencimento", fonteCabecalho));
		t8.setBackgroundColor(new Color(236, 235, 234));
		table.addCell(t8);
		
		Cell t5 = new Cell(new Phrase("Valor", fonteCabecalho));
		t5.setBackgroundColor(new Color(236, 235, 234));
		table.addCell(t5);
	}
	
	
	private Table criarObjetoTabela(int numColunas, float[] headerWidths) {
	        try {
	            Table aTable = new Table(numColunas);

	            aTable.setPadding(1);
	            aTable.setSpacing(0);

	            aTable.setWidths(headerWidths);

	            aTable.widthPercentage();
	            aTable.setWidth(100);
	            aTable.setBorder(0);

	            aTable.setSpaceBetweenCells(0);

	            aTable.setDefaultCellBorderWidth(0);
	            aTable.setBorder(0);

	            return aTable;
	        } catch (BadElementException e) {
	            throw new RuntimeException("Erro definindo largura do cabeçalho", e);
	        }
	    }

}

